/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ships.core.icc;

import java.util.logging.Level;
import java.util.logging.Logger;
import ships.core.icc.io.InvalidIccProfileException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ships.core.icc.IccDefs.icValidateStatus;
import ships.core.icc.IccTagBasic.CIccTag;
import ships.core.icc.icProfileHeader.icHeader;
import ships.core.icc.icProfileHeader.icProfileID;
import ships.core.icc.icProfileHeader.icTag;
import ships.core.icc.icProfileHeader.icTagSignature;
import ships.core.icc.icProfileHeader.icTagTypeSignature;
import ships.core.icc.io.IccBufferedInputStream;
import ships.core.icc.io.IccFileInputStream;
import ships.core.icc.io.IccInputStream;
import ships.core.icc.io.IccOutputStream;

/**
 *
 * @author fqhuy
 */
public class IccProfile {

    public static enum icProfileIDSaveMethod {

        icVersionBasedID,
        icAlwaysWriteID,
        icNeverWriteID,
    }

    public static class IccTagEntry {

        public IccTagEntry() {
            //TagInfo =
        }
        icTag TagInfo = new icTag();
        CIccTag pTag;
    }

    public IccProfile() {
        header = new icProfileHeader.icHeader();
        tags = new ArrayList<IccTagEntry>();
        iStream = null;
        oStream = null;
        tagVals = new ArrayList<CIccTag>();
    }

    public IccProfile(IccProfile Profile) {
    }

    public IccProfile assigns(IccProfile Profile) {
        throw new UnsupportedOperationException();
    }

    public CIccTag FindTag(int sig) {
        throw new UnsupportedOperationException();
    }

    public void AttachTag(int sig, CIccTag pTag) {
        throw new UnsupportedOperationException();
    }

    public void DeleteTag(int sig) {
        throw new UnsupportedOperationException();
    }

    public IccBufferedInputStream GetTagIO(int sig) {
        throw new UnsupportedOperationException();
    } //caller should delete returned result

    public void ReadTags(IccProfile pProfile) {
        throw new UnsupportedOperationException();
    } 

    public void Attach(IccInputStream is, IccOutputStream os) throws IOException{
        this.oStream = os;
        try {
            Attach(is);
        } catch (InvalidIccProfileException ex) {
            Logger.getLogger(IccProfile.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void Attach(IccInputStream is) throws IOException, InvalidIccProfileException {
        ReadBasic(is);
        iStream = is;
    }

    public void Detach() {
        throw new UnsupportedOperationException();
    }

    public void Read(IccIO pIO) {
        throw new UnsupportedOperationException();
    }

    public icValidateStatus ReadValidate(IccIO pIO, String sReport) {
        throw new UnsupportedOperationException();
    }

    public void Write(IccIO pIO, icProfileIDSaveMethod nWriteId) {
        throw new UnsupportedOperationException();
    }

    public void InitHeader() {
        throw new UnsupportedOperationException();
    }

    public icValidateStatus Validate(String sReport) {
        throw new UnsupportedOperationException();
    }

    public int GetSpaceSamples() {
        throw new UnsupportedOperationException();
    }

    public void AreTagsUnique() {
        throw new UnsupportedOperationException();
    }
    // public void IsTagPresent(int sig) { return (GetTag(sig)!=null);}

    protected void Cleanup() {
        // m_pAttachIO.
        //throw new UnsupportedOperationException();
    }

    protected IccTagEntry GetTag(int sig) {
        throw new UnsupportedOperationException();
    }

    protected IccTagEntry GetTag(CIccTag pTag) {
        throw new UnsupportedOperationException();
    }

    protected void ReadBasic(IccInputStream is) throws IOException, InvalidIccProfileException {
        header.size = is.readInt();
        header.cmmId = is.readInt();
        header.version = is.readInt();
        header.deviceClass = icProfileHeader.icProfileClassSignature.fromInt(is.readInt());
        header.colorSpace = icProfileHeader.icColorSpaceSignature.fromInt(is.readInt());
        header.pcs = icProfileHeader.icColorSpaceSignature.fromInt(is.readInt());
        header.date.year = is.readShort();
        header.date.month = is.readShort();
        header.date.day = is.readShort();
        header.date.hours = is.readShort();
        header.date.minutes = is.readShort();
        header.date.seconds = is.readShort();
        header.magic = is.readInt();
        header.platform = icProfileHeader.icPlatformSignature.fromInt(is.readInt());
        header.flags = is.readInt();
        header.manufacturer = is.readInt();
        header.model = is.readInt();
        header.attributes = is.readLong();
        header.renderingIntent = is.readInt();
        header.illuminant.X = is.readInt();
        header.illuminant.Y = is.readInt();
        header.illuminant.Z = is.readInt();
        header.creator = is.readInt();
        byte buff[] = new byte[icProfileHeader.icProfileID.length];
        is.read(buff);
        header.profileID = new icProfileHeader.icProfileID(buff);
        buff = new byte[header.reserved.length];
        is.read(buff);
        header.reserved = buff;

        if (header.magic != icProfileHeader.icMagicNumber) {
            throw new InvalidIccProfileException();
        }

        int count = 0;
        IccTagEntry TagEntry = new IccTagEntry();

        TagEntry.pTag = null;

        count = is.readInt();

        //Read TagDir
        for (int i = 0; i < count; i++) {
            TagEntry.TagInfo.sig = icProfileHeader.icTagSignature.fromInt(is.readInt());
            TagEntry.TagInfo.offset = is.readInt();
            TagEntry.TagInfo.size = is.readInt();
            tags.add(TagEntry);
        }

        //return true;
    }

    public void LoadTag(IccTagEntry pTagEntry, IccIO pIO) {
        throw new UnsupportedOperationException();
    }

    public void DetachTag(CIccTag pTag) {
        throw new UnsupportedOperationException();
    }

    // Profile Validation functions
    protected icValidateStatus CheckRequiredTags(String sReport) {
        throw new UnsupportedOperationException();
    }

    public void CheckTagExclusion(String sReport) {
        throw new UnsupportedOperationException();
    }

    protected icValidateStatus CheckHeader(String sReport) {
        throw new UnsupportedOperationException();
    }

    protected icValidateStatus CheckTagTypes(String sReport) {
        throw new UnsupportedOperationException();
    }

    public void IsTypeValid(icTagSignature tagSig, icTagTypeSignature typeSig) {
        throw new UnsupportedOperationException();
    }

    public void CheckFileSize(IccIO pIO) {
        throw new UnsupportedOperationException();
    }
    
    protected icHeader header;
    protected List<IccTagEntry> tags;
    protected IccInputStream iStream;
    protected IccOutputStream oStream;
    //protected IccIO m_pAttachIO;
    protected List<CIccTag> tagVals;

    public static IccProfile ReadIccProfile(String szFilename) {
        throw new UnsupportedOperationException();
    }

    public static IccProfile ReadIccProfile(byte[] pMem, int nSize) {
        throw new UnsupportedOperationException();
    }

    public static IccProfile OpenIccProfile(String szFilename) throws IOException{
        IccFileInputStream is = new IccFileInputStream(new File(szFilename));

        IccProfile pIcc = new IccProfile();
        try {
            pIcc.Attach(is);
        } catch (InvalidIccProfileException ex) {
            Logger.getLogger(IccProfile.class.getName()).log(Level.SEVERE, null, ex);
        }

        return pIcc;
    }

    public static IccProfile OpenIccProfile(byte[] pMem, int nSize) {
        throw new UnsupportedOperationException();
    }

    public static IccProfile ValidateIccProfile(IccIO pIO, String sReport, icValidateStatus nStatus) {
        throw new UnsupportedOperationException();
    }

    public static IccProfile ValidateIccProfile(String szFilename, String sReport, icValidateStatus nStatus) {
        throw new UnsupportedOperationException();
    }

    public static boolean SaveIccProfile(String szFilename, IccProfile pIcc, icProfileIDSaveMethod nWriteId) {
        throw new UnsupportedOperationException();
    }

    public static void CalcProfileID(IccIO pIO, icProfileID profileID) {
        throw new UnsupportedOperationException();
    }

    public static boolean CalcProfileID(String szFilename, icProfileID profileID) {
        throw new UnsupportedOperationException();
    }
}
